# views.py 路由 + 视图函数
import copy
import json
import os
import time
from datetime import datetime

import cv2
import torch
from flask import request, jsonify, Response
from flask import  Blueprint
import hashlib
from werkzeug.utils import secure_filename
from .utils.api_utils import APIUtils
from .model.detect_rec_plate import det_rec_plate, draw_result, load_model
from .model.plate_recognition.plate_rec import init_model

from .models import *
from .utils.config import ConfigManager
blus = Blueprint("user", __name__)

# 获取当前文件的绝对路径
project_path = os.path.dirname(os.path.abspath(__file__))
# 使用GPU还是CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")


# 上传图片检测
@blus.route('/upload_image', methods=['POST'])
def api_upload_image():
    # 检测是否收到图片
    if 'file' not in request.files:
        return APIUtils.error_response("图片没有接收到!", status_code=400)
    # 获取图片
    file = request.files['file']
    if file.filename == '':
        return APIUtils.error_response("未选择图片!", status_code=400)
    filename = secure_filename(file.filename)
    # 拼接目标路径
    input_path = os.path.join(project_path,ConfigManager.get_value("static_img"), filename)
    # 确保目录存在
    os.makedirs(os.path.dirname(input_path), exist_ok=True)
    # 保存上传的图片
    file.save(input_path)
    # 使用 YOLOv8 处理图片
    img = cv2.imread(input_path)
    img_ori = copy.deepcopy(img)

    # 原始检测模型位置
    detect_model = os.path.join(project_path, ConfigManager.get_value("detect_model"))
    rec_model = os.path.join(project_path, ConfigManager.get_value("rec_model"))
    # 初始化yolov8识别模型
    detect_model = load_model(detect_model, device)
    # 初始化识别模型
    plate_rec_model = init_model(device , rec_model, is_color=True)
    detect_model.eval()
    # 运行检测和车牌识别
    result_list = det_rec_plate(img, img_ori, detect_model, plate_rec_model)
    # 将结果画在图上
    ori_img = draw_result(img, result_list)
    # 保存处理后的图片
    save_img_path = os.path.join(project_path,ConfigManager.get_value("model_output"),file.filename)
    cv2.imwrite(save_img_path, ori_img)
    # 可选择返回处理结果（例如检测结果）
    # 保存历史结果
    # 创建新用户
    # 获取当前日期和时间
    now = datetime.now()
    # 按照 YYYY-MM-DD mm:分:秒 的格式表示
    formatted_time = now.strftime('%Y-%m-%d %H:%M:%S')
    add_result = HistoryDetection(results=str(result_list), processed_image="model_output/" + file.filename,image= "img/" + file.filename,create_time=formatted_time)
    db.session.add(add_result)
    db.session.commit()

    return APIUtils.success_response( message="添加成功!", data={
            "results": result_list,
              "processed_image": "http://127.0.0.1:5000/static/model_output/" + file.filename}
    )


@blus.route('/upload_video', methods=['GET'])
def upload_video():
    detect_model = os.path.join(project_path, ConfigManager.get_value("detect_model"))
    rec_model = os.path.join(project_path, ConfigManager.get_value("rec_model"))
    # 初始化yolov8识别模型
    detect_model = load_model(detect_model, device)
    # 初始化识别模型
    plate_rec_model = init_model(device, rec_model, is_color=True)
    detect_model.eval()

    # 打开视频文件
    cap = cv2.VideoCapture("F:\\machine-detection\\App\\static\\img\\20240922_105232.mp4")
    def generate():
        count = 0
        while cap.isOpened():
            ret, img = cap.read()
            if not ret:
                print("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddd")
                break  # 如果没有读取到帧，退出循环·
            img_ori = copy.deepcopy(img)
            result_list = det_rec_plate(img, img_ori, detect_model, plate_rec_model)

            save_path = f"F:\\machine-detection\\App\\static\\model_output\\frame_{count}.jpg"

            ori_img = draw_result(img, result_list)  # 将结果画在图上
            cv2.imwrite(save_path, ori_img)

            response = {
                "results": result_list,
                "processed_image": f"http://127.0.0.1:5000/static/model_output/" + f"frame_{count}.jpg"}
            count += 1

            yield f"data: {json.dumps(response)}\n\n"
        cap.release()
        print("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddd")
    return Response(generate(), content_type='text/event-stream')


@blus.route('/history', methods=['GET'])
def get_history():
    data = HistoryDetection.query.order_by(HistoryDetection.create_time.desc()).all()
    # 将查询结果的每个对象转换为字典
    data_list = [item.to_dict() for item in data]
    return APIUtils.success_response(
        message="查询成功成功!",
        data = data_list
    )


@blus.route('/config', methods=['POST'])
def add_config():
    required_fields = ['name', 'key','value']
    is_valid, message = APIUtils.validate_json(request.json, required_fields)
    if not is_valid:
        return APIUtils.error_response(message, status_code=400)
    name = request.json['name']
    key = request.json['key']
    value = request.json['value']
    config = Config(name=name, key=key,value=value)
    db.session.add(config)
    db.session.commit()
    return APIUtils.success_response(message="添加成功!")

# @blus.route('/config/<string:key>', methods=['PUT'])
# def update_config(key):
#     data = request.json
#     try:
#         ConfigManager.update_config(key, data['value'])
#         return {"message": "配置项更新成功！"}, 200
#     except ValueError as e:
#         return {"message": str(e)}, 400
#
# @blus.route('/config/<string:key>', methods=['DELETE'])
# def delete_config(key):
#     try:
#         ConfigManager.delete_config(key)
#         return {"message": "配置项删除成功！"}, 200
#     except ValueError as e:
#         return {"message": str(e)}, 400


# 注册
@blus.route('/register', methods=['POST'])
def user_register():
    required_fields = ['username', 'password']
    is_valid, message = APIUtils.validate_json(request.json, required_fields)
    if not is_valid:
        return APIUtils.error_response(message, status_code=400)
    username = request.json['username']
    password = request.json['password']

    # 检查用户名是否已存在
    existing_user = User.query.filter_by(username=username).first()
    if existing_user:
        return APIUtils.error_response("用户名已经存在!", status_code=400)

    # 哈希处理密码
    hashed_password = hashlib.sha256(password.encode()).hexdigest()

    # 创建新用户
    new_user = User(username=username, password=hashed_password)

    db.session.add(new_user)
    db.session.commit()

    return APIUtils.success_response(message="登录成功!")

@blus.route('/login', methods=['POST'])
def user_login():
    required_fields = ['username', 'password']
    is_valid, message = APIUtils.validate_json(request.json, required_fields)
    if not is_valid:
        return APIUtils.error_response(message, status_code=400)
    username = request.json['username']
    password = request.json['password']
    user = User.query.filter_by(username=username).first()
    if user is None:
        return APIUtils.error_response("用户名或密码错误！", status_code=401)
    hashed_password = hashlib.sha256(password.encode()).hexdigest()
    if hashed_password != user.password:
        return APIUtils.error_response("用户名或密码错误！", status_code=401)
    return APIUtils.success_response(data={'user_id': user.id, 'username': user.username}, message="登录成功！")

@blus.route('/change_password', methods=['POST'])
def change_password():
    required_fields = ['username', 'old_password', 'new_password']
    is_valid, message = APIUtils.validate_json(request.json, required_fields)

    if not is_valid:
        return APIUtils.error_response(message, status_code=400)

    username = request.json['username']
    old_password = request.json['old_password']
    new_password = request.json['new_password']

    user = User.query.filter_by(username=username).first()

    if user is None:
        return APIUtils.error_response("用户不存在！", status_code=404)
    hashed_old_password = hashlib.sha256(old_password.encode()).hexdigest()

    if hashed_old_password != user.password:
        return APIUtils.error_response("旧密码错误！", status_code=401)

    # 哈希处理新密码
    hashed_new_password = hashlib.sha256(new_password.encode()).hexdigest()
    user.password = hashed_new_password

    db.session.commit()
    return APIUtils.success_response(message="密码修改成功！")

@blus.route('/delete_user', methods=['DELETE'])
def delete_user():
    required_fields = ['username']
    is_valid, message = APIUtils.validate_json(request.json, required_fields)

    if not is_valid:
        return APIUtils.error_response(message, status_code=400)

    username = request.json['username']

    # 检查是否为 admin 用户
    if username.lower() == 'admin':
        return APIUtils.error_response("无法删除管理员账户！", status_code=403)

    user = User.query.filter_by(username=username).first()

    if user is None:
        return APIUtils.error_response("用户不存在！", status_code=404)
    db.session.delete(user)
    db.session.commit()

    return APIUtils.success_response(message="用户删除成功！")





# from flask import Response
#
# @app.route('/video_feed')
# def video_feed():
#     """打开摄像头并生成视频流"""
#     cap = cv2.VideoCapture(0)  # 打开默认摄像头
#     if not cap.isOpened():
#         return "无法打开摄像头", 500
#     def generate_frames():
#         while True:
#             success, frame = cap.read()  # 读取帧
#             if not success:
#                 break
#             # 使用 YOLOv8 和车牌识别模型处理当前帧
#             result_list = det_rec_plate(frame, frame.copy(), detect_model, plate_rec_model)
#             ori_img = draw_result(frame, result_list)
#             # 编码为 JPEG 格式
#             _, buffer = cv2.imencode('.jpg', ori_img)
#             frame = buffer.tobytes()
#             yield (b'--frame\r\n'
#                    b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
#     return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
